#!/bin/bash

# Java environment settings
#export JAVA_HOME=/home/software/jdk-17.0.11/
#export PATH=$JAVA_HOME/bin:$PATH
#export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar


# Global variables
KILL_PORT=8200
SERVER_PATH=""
SERVER_PROPERTIES="--spring.profiles.active=prod"
SERVER_PORT="--server.port=8200"
JAVA_OPTS="-Xms1024m -Xmx4024m -Xmn4024m -Dfile.encoding=UTF-8"
CLOSE_SWAGGER=" --knife4j.enable=false --springdoc.swagger-ui.enabled=false --springdoc.api-docs.enabled=false "
JAVA_PARAMS=""
SPRING_PARAMS=""
SWAGGER_DISABLED=false
BACKGROUND_MODE=true

# Function to display usage information
show_usage() {
    echo "\n\033[1;36m=== Usage Information ===\033[0m"
    echo "\033[1;33m[Usage]\033[0m `basename $0` {start|stop|restart} [-j <jar path>] [-f <profile>] [-p <port>] [-v <JVM options>] [-s <Spring params>]"
    echo "\n\033[1;36m=== Parameter Examples ===\033[0m"
    echo "\033[1;32m[-j ./dmp-api-1.0-SNAPSHOT.jar]\033[0m  \033[1;30m# JAR file path\033[0m"
    echo "\033[1;32m[-f prod]\033[0m                                                     \033[1;30m# Spring profile\033[0m"
    echo "\033[1;32m[-p 8200]\033[0m                                                     \033[1;30m# Application port\033[0m"
    echo "\033[1;32m[-v -Xms1024m -Xmx4024m -Xmn4024m -XX:+UseParallelGC -XX:+UseParallelOldGC -Dfile.encoding=UTF-8]\033[0m  \033[1;30m# JVM options\033[0m"
    echo "\033[1;32m[-s --spring.datasource.url=jdbc:mysql://localhost:3306/db_file]\033[0m   \033[1;30m# Spring parameters\033[0m"
    echo "\033[1;32m[-d -DREDIS_HOST="127.0.0.1"]\033[0m   \033[1;30m# Java parameters\033[0m"
    echo "\033[1;32m[-k true]\033[0m                                                     \033[1;30m# Disable Swagger\033[0m"
    echo "\033[1;32m[-b true]\033[0m                                                     \033[1;30m# Run in background (default: true)\033[0m"
    echo "\n\033[1;36m=== Example Commands ===\033[0m"
    echo "\033[1;35m./`basename $0` start -p 8200 -f dev\033[0m"
    echo "\033[1;35m./`basename $0` stop -p 8200\033[0m"
    echo "\033[1;35m./`basename $0` restart -j myapp.jar -p 8200 -f prod\033[0m"
}

# Function to process command line arguments
parse_arguments() {
    while getopts j:f:p:v:s:d:k:b: OPT; do
        case ${OPT} in
        j) SERVER_PATH=${OPTARG} ;; # jar path
        f) SERVER_PROPERTIES="--spring.profiles.active=${OPTARG}" ;; # configuration file
        p) SERVER_PORT="--server.port=${OPTARG}"; KILL_PORT=${OPTARG} ;; # port number
        v) JAVA_OPTS="${OPTARG}" ;; # JVM options
        s) SPRING_PARAMS="${OPTARG}" ;; # Spring parameters
        d) JAVA_PARAMS="${OPTARG}" ;; # java env
        k) SWAGGER_DISABLED=$(echo "${OPTARG}" | tr '[:upper:]' '[:lower:]') ;; # swagger control
        b) BACKGROUND_MODE=$(echo "${OPTARG}" | tr '[:upper:]' '[:lower:]') ;; # background mode control
        \?)
            show_usage
            exit 1
            ;;
        esac
    done

    # Shift to process the remaining arguments (commands)
    shift $((OPTIND - 1))

    # If jar path is not provided, search for a jar in the current directory
    if [ -z "$SERVER_PATH" ]; then
        SERVER_PATH=$(find . -maxdepth 1 -type f -name "*.jar")
        if [ -z "$SERVER_PATH" ]; then
            echo "\033[1;31m[ERROR]\033[0m No JAR file found in current directory"
            exit 1
        fi
    fi
}

# Function to print the current Java environment
print_java_env() {
    echo "\n\033[1;36m============== Current Java Environment ==============\033[0m"
    echo "\033[1;32mJAVA_HOME:\033[0m $JAVA_HOME"
    echo "\033[1;32mJava version:\033[0m"
    java -version
    echo "\033[1;36m====================================================\033[0m"
}

# Function to print startup parameters
print_startup_params() {
    echo  "\n\033[1;36m---------- Java Startup Parameters ----------\033[0m"
    echo  "\033[1;32mJava options:\033[0m ${JAVA_OPTS}"
    echo  "\033[1;32mJAR path:\033[0m ${SERVER_PATH}"
    echo  "\033[1;32mPort:\033[0m ${SERVER_PORT}"
    echo  "\033[1;32mProfile:\033[0m ${SERVER_PROPERTIES}"
    echo  "\033[1;32mSpring params:\033[0m ${SPRING_PARAMS}"
    echo  "\033[1;32mJava params:\033[0m ${JAVA_PARAMS}"
    echo  "\033[1;32mSwagger disabled:\033[0m ${SWAGGER_DISABLED}"
    echo  "\033[1;32mBackground mode:\033[0m ${BACKGROUND_MODE}"
    echo  "\033[1;36m--------------------------------------------\033[0m"
}

# Stop application
stop() {
    echo  "\n\033[1;33m[STOP]\033[0m Stopping application on port \033[1;35m${KILL_PORT}\033[0m..."
    PID=$(lsof -ti:${KILL_PORT})
    if [ -n "$PID" ]; then
        kill -9 $PID
        echo  "\033[1;32m[SUCCESS]\033[0m Application on port \033[1;35m${KILL_PORT}\033[0m stopped successfully"
    else
        echo  "\033[1;33m[INFO]\033[0m No application running on port \033[1;35m${KILL_PORT}\033[0m"
    fi
    sleep 1
}

# Start application
start() {
    echo  "\n\033[1;33m[START]\033[0m Initializing application startup..."
    print_java_env

    # Check if jar file exists
    if [ ! -f "$SERVER_PATH" ]; then
        echo  "\033[1;31m[ERROR]\033[0m JAR file not found: \033[1;35m$SERVER_PATH\033[0m"
        exit 1
    fi

    echo  "\033[1;32m[INFO]\033[0m JAR file exists: \033[1;35m$SERVER_PATH\033[0m"
    print_startup_params

    FINAL_PARAMS="$SERVER_PORT $SERVER_PROPERTIES $SPRING_PARAMS"
    if [ "$SWAGGER_DISABLED" = "true" ]; then
        FINAL_PARAMS="$FINAL_PARAMS $CLOSE_SWAGGER"
    fi
	if [ "$BACKGROUND_MODE" = "true" ]; then
		echo "\\033[1;32m[INFO]\\033[0m Starting in background mode..."
		# creat temp file
		TEMP_LOG="/tmp/spring-boot-$(date +%Y%m%d_%H%M%S)_startup_$KILL_PORT.log"

		# run application
		nohup java $JAVA_OPTS $JAVA_PARAMS -jar $SERVER_PATH $FINAL_PARAMS > "$TEMP_LOG" 2>&1 &

        # Store the PID
        APP_PID=$!

		# 等待几秒钟让应用启动
        sleep 3

        echo  "\033[1;32m[INFO]\033[0m Application process ID: \033[1;35m${APP_PID}\033[0m"
		# SHOW START LOG
		if [ -f "$TEMP_LOG" ]; then
			echo "\\033[1;36m=== Startup Log ===\\033[0m"
			tail -f "$TEMP_LOG" &
			TAIL_PID=$!
			echo  "\033[1;32m[INFO]\033[0m TAIL_PID process ID: \033[1;35m${TAIL_PID}\033[0m"
			sleep 20
			kill $TAIL_PID 2>/dev/null
		    # Remove log file in background after application has started
			( sleep 2; rm -f "$TEMP_LOG" ) &
			echo "\\033[1;36m=== End of Startup Log ===\\033[0m"
		fi
	else
		echo "\\033[1;32m[INFO]\\033[0m Starting in foreground mode..."
		java $JAVA_OPTS $JAVA_PARAMS -jar $SERVER_PATH $FINAL_PARAMS
	fi

    if [ "$BACKGROUND_MODE" = "true" ]; then
        echo  "\033[1;32m[SUCCESS]\033[0m Application started successfully in background"
        echo  "\033[1;32m[INFO]\033[0m Running on port \033[1;35m${KILL_PORT}\033[0m"
    fi
    echo  "\033[1;32m[INFO]\033[0m Command: \033[1;35mjava $JAVA_OPTS $JAVA_PARAMS  -jar $SERVER_PATH $FINAL_PARAMS\033[0m"
}

# Restart application
restart() {
    echo  "\n\033[1;33m[RESTART]\033[0m Restarting application..."
    stop
    sleep 2
    start
}

# Main execution
main() {
    if [ $# -lt 1 ]; then
        show_usage
        exit 1
    fi

    COMMAND=$1
    shift

    # Parse remaining arguments
    parse_arguments "$@"

    case "$COMMAND" in
        start)
            start
            ;;
        stop)
            stop
            ;;
        restart)
            restart
            ;;
        *)
            echo  "\033[1;31m[ERROR]\033[0m Unknown command: \033[1;35m$COMMAND\033[0m"
            show_usage
            exit 1
            ;;
    esac
}

# Execute main function with all arguments
main "$@"
